#include "projectwelcomepage.h"
#include "pf_project.h"
#include "pf_sessionmanager.h"
#include "pf_projecttree.h"
#include "pf_projectexplorer.h"

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/constants.h>
#include <coreplugin/context.h>
#include <coreplugin/icore.h>
#include <coreplugin/iwizardfactory.h>
#include <coreplugin/pagemanager.h>

#include <utils/algorithm.h>
//#include <utils/fileutils.h>
#include <utils/stringutils.h>
//#include <utils/theme/theme.h>

#include <QAbstractItemDelegate>
#include <QAction>
#include <QBoxLayout>
#include <QDir>
#include <QFileInfo>
#include <QHeaderView>
#include <QHelpEvent>
#include <QLabel>
#include <QPainter>
#include <QToolTip>
#include <QTreeView>
#include <QApplication>

using namespace Core;
using namespace Utils;

const int LINK_HEIGHT = 35;
const int SESSION_LINE_HEIGHT = 30;
const char PROJECT_BASE_ID[] = "Welcome.OpenRecentProject";

namespace ProjectExplorer {
//namespace Internal {

//ProjectModel::ProjectModel(QObject *parent)
//    : QAbstractListModel(parent)
//{
//    connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::recentProjectsChanged,
//            this, &ProjectModel::resetProjects);
//}

//int ProjectModel::rowCount(const QModelIndex &) const
//{
//    return ProjectExplorerPlugin::recentProjects().count();
//}

//QVariant ProjectModel::data(const QModelIndex &index, int role) const
//{
//    QPair<QString,QString> data = ProjectExplorerPlugin::recentProjects().at(index.row());
//    switch (role) {
//    case Qt::DisplayRole:
//        return data.second;
//    case Qt::ToolTipRole:
//        return data.first;
//    case FilePathRole:
//        return data.first;
//    case PrettyFilePathRole:
//        return Utils::withTildeHomePath(data.first);
//    case ShortcutRole: {
//        const Id projectBase = PROJECT_BASE_ID;
//        if (Command *cmd = ActionManager::command(projectBase.withSuffix(index.row() + 1)))
//            return cmd->keySequence().toString(QKeySequence::NativeText);
//        return QVariant();
//    }
//    default:
//        return QVariant();
//    }
//}

//QHash<int, QByteArray> ProjectModel::roleNames() const
//{
//    static QHash<int, QByteArray> extraRoles{
//        {Qt::DisplayRole, "displayName"},
//        {FilePathRole, "filePath"},
//        {PrettyFilePathRole, "prettyFilePath"}
//    };

//    return extraRoles;
//}

//void ProjectModel::resetProjects()
//{
//    beginResetModel();
//    endResetModel();
//}

///////////////////

ProjectWelcomePage::ProjectWelcomePage()
{
//    const int actionsCount = 9;
//    Context welcomeContext(Core::Constants::C_WELCOME_MODE);

//    const Id projectBase = PROJECT_BASE_ID;
//    const Id sessionBase = SESSION_BASE_ID;
//    for (int i = 1; i <= actionsCount; ++i) {
//        auto act = new QAction(tr("Open Session #%1").arg(i), this);
//        Command *cmd = ActionManager::registerAction(act, sessionBase.withSuffix(i), welcomeContext);
//        cmd->setDefaultKeySequence(QKeySequence((useMacShortcuts ? tr("Ctrl+Meta+%1") : tr("Ctrl+Alt+%1")).arg(i)));
//        connect(act, &QAction::triggered, this, [this, i] {
//            if (i <= m_sessionModel->rowCount())
//                openSessionAt(i - 1);
//        });

//        act = new QAction(tr("Open Recent Project #%1").arg(i), this);
//        cmd = ActionManager::registerAction(act, projectBase.withSuffix(i), welcomeContext);
//        cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+%1").arg(i)));
//        connect(act, &QAction::triggered, this, [this, i] {
//            if (i <= m_projectModel->rowCount(QModelIndex()))
//                openProjectAt(i - 1);
//        });
//    }
}

Core::Id ProjectWelcomePage::id() const
{
    return "Develop";
}

void ProjectWelcomePage::reloadWelcomeScreenData() const
{
//    if (m_sessionModel)
//        m_sessionModel->resetSessions();
//    if (m_projectModel)
//        m_projectModel->resetProjects();
}

void ProjectWelcomePage::newProject()
{
//    ProjectExplorerPlugin::openNewProjectDialog();
}

void ProjectWelcomePage::openProject()
{
//    ProjectExplorerPlugin::openOpenProjectDialog();
}

void ProjectWelcomePage::openSessionAt(int index)
{
//    QTC_ASSERT(m_sessionModel, return);
//    m_sessionModel->switchToSession(m_sessionModel->sessionAt(index));
}

void ProjectWelcomePage::openProjectAt(int index)
{
//    QTC_ASSERT(m_projectModel, return);
//    const QString projectFile = m_projectModel->data(m_projectModel->index(index, 0),
//                                                     ProjectModel::FilePathRole).toString();
//    ProjectExplorerPlugin::openProjectWelcomePage(projectFile);
}

///////////////////

//static QColor themeColor(Theme::Color role)
//{
//    return Utils::creatorTheme()->color(role);
//}

static QFont sizedFont(int size, const QWidget *widget, bool underline = false)
{
    QFont f = widget->font();
    f.setPixelSize(size);
    f.setUnderline(underline);
    return f;
}

//static QPixmap pixmap(const QString &id, const Theme::Color &color)
//{
//    const QString fileName = QString(":/welcome/images/%1.png").arg(id);
//    return Icon({{fileName, color}}, Icon::Tint).pixmap();
//}

//class BaseDelegate : public QAbstractItemDelegate
//{
//protected:
//    virtual QString entryType() = 0;
//    virtual QRect toolTipArea(const QRect &itemRect, const QModelIndex &) const
//    {
//        return itemRect;
//    }
//    virtual int shortcutRole() const = 0;

//    bool helpEvent(QHelpEvent *ev, QAbstractItemView *view,
//                   const QStyleOptionViewItem &option, const QModelIndex &idx) final
//    {
//        if (!toolTipArea(option.rect, idx).contains(ev->pos())) {
//            QToolTip::hideText();
//            return false;
//        }

//        QString shortcut = idx.data(shortcutRole()).toString();

//        QString name = idx.data(Qt::DisplayRole).toString();
//        QString tooltipText;
//        const QString type = entryType();
//        if (shortcut.isEmpty())
//            tooltipText = ProjectWelcomePage::tr("Open %1 \"%2\"").arg(type, name);
//        else
//            tooltipText = ProjectWelcomePage::tr("Open %1 \"%2\" (%3)").arg(type, name, shortcut);

//        if (tooltipText.isEmpty())
//            return false;

//        QToolTip::showText(ev->globalPos(), tooltipText, view);
//        return true;
//    }
//};

//class SessionDelegate : public BaseDelegate
//{
//protected:
//    QString entryType() override
//    {
//        return ProjectWelcomePage::tr("session", "Appears in \"Open session <name>\"");
//    }
//    QRect toolTipArea(const QRect &itemRect, const QModelIndex &idx) const override
//    {
//        // in expanded state bottom contains 'Clone', 'Rename', etc links, where the tool tip
//        // would be confusing
//        const bool expanded = m_expandedSessions.contains(idx.data(Qt::DisplayRole).toString());
//        return expanded ? itemRect.adjusted(0, 0, 0, -LINK_HEIGHT) : itemRect;
//    }
//    int shortcutRole() const override { return SessionModel::ShortcutRole; }

//public:
//    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final
//    {
//        static const QPixmap sessionIcon = pixmap("session", Theme::Welcome_ForegroundSecondaryColor);

//        const QRect rc = option.rect;
//        const QString sessionName = idx.data(Qt::DisplayRole).toString();

//        const QPoint mousePos = option.widget->mapFromGlobal(QCursor::pos());
//        //const bool hovered = option.state & QStyle::State_MouseOver;
//        const bool hovered = option.rect.contains(mousePos);
//        const bool expanded = m_expandedSessions.contains(sessionName);
//        if (hovered)
//            painter->fillRect(expanded ? rc : rc.adjusted(0, 0, -24, 0), hoverColor);

//        const int x = rc.x();
//        const int x1 = x + 36;
//        const int y = rc.y();
//        const int firstBase = y + 18;

//        painter->drawPixmap(x + 11, y + 6, sessionIcon);

//        if (hovered && !expanded) {
//            const QRect arrowRect = rc.adjusted(rc.width() - 24, 0, 0, 0);
//            if (arrowRect.contains(mousePos))
//                painter->fillRect(arrowRect, hoverColor);
//        }

//        if (hovered || expanded) {
//            static const QPixmap arrowUp = pixmap("expandarrow",Theme::Welcome_ForegroundSecondaryColor);
//            static const QPixmap arrowDown = QPixmap::fromImage(arrowUp.toImage().mirrored(false, true));
//            painter->drawPixmap(rc.right() - 20, y + 7, expanded ? arrowDown : arrowUp);
//        }

//        if (idx.row() < 9) {
//            painter->setPen(foregroundColor2);
//            painter->setFont(sizedFont(10, option.widget));
//            painter->drawText(x + 3, firstBase, QString::number(idx.row() + 1));
//        }

//        const bool isLastSession = idx.data(SessionModel::LastSessionRole).toBool();
//        const bool isActiveSession = idx.data(SessionModel::ActiveSessionRole).toBool();
//        const bool isDefaultVirgin = SessionManager::isDefaultVirgin();

//        QString fullSessionName = sessionName;
//        if (isLastSession && isDefaultVirgin)
//            fullSessionName = ProjectWelcomePage::tr("%1 (last session)").arg(fullSessionName);
//        if (isActiveSession && !isDefaultVirgin)
//            fullSessionName = ProjectWelcomePage::tr("%1 (current session)").arg(fullSessionName);

//        const QRect switchRect = QRect(x, y, rc.width() - 24, SESSION_LINE_HEIGHT);
//        const bool switchActive = switchRect.contains(mousePos);
//        painter->setPen(linkColor);
//        painter->setFont(sizedFont(13, option.widget, switchActive));
//        painter->drawText(x1, firstBase, fullSessionName);
//        if (switchActive)
//            m_activeSwitchToRect = switchRect;

//        if (expanded) {
//            painter->setPen(textColor);
//            painter->setFont(sizedFont(12, option.widget));
//            const QStringList projects = SessionManager::projectsForSessionName(sessionName);
//            int yy = firstBase + 25;
//            QFontMetrics fm(option.widget->font());
//            for (const QString &project : projects) {
//                // Project name.
//                QFileInfo fi(project);
//                QString completeBase = fi.completeBaseName();
//                painter->setPen(textColor);
//                painter->drawText(x1, yy, completeBase);
//                yy += 18;

//                // Project path.
//                QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(project));
//                painter->setPen(foregroundColor1);
//                painter->drawText(x1, yy, fm.elidedText(pathWithTilde, Qt::ElideMiddle, rc.width() - 40));
//                yy += 22;
//            }

//            yy += 5;
//            int xx = x1;
//            const QStringList actions = {
//                ProjectWelcomePage::tr("Clone"),
//                ProjectWelcomePage::tr("Rename"),
//                ProjectWelcomePage::tr("Delete")
//            };
//            for (int i = 0; i < 3; ++i) {
//                const QString &action = actions.at(i);
//                const int ww = fm.width(action);
//                const QRect actionRect(xx, yy - 10, ww, 15);
//                const bool isForcedDisabled = (i != 0 && sessionName == "default");
//                const bool isActive = actionRect.contains(mousePos) && !isForcedDisabled;
//                painter->setPen(isForcedDisabled ? disabledLinkColor : linkColor);
//                painter->setFont(sizedFont(12, option.widget, isActive));
//                painter->drawText(xx, yy, action);
//                if (i < 2) {
//                    xx += ww + 14;
//                    int pp = xx - 7;
//                    painter->setPen(textColor);
//                    painter->drawLine(pp, yy - 10, pp, yy);
//                }
//                if (isActive)
//                    m_activeActionRects[i] = actionRect;
//            }
//        }
//    }

//    QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &idx) const final
//    {
//        int h = SESSION_LINE_HEIGHT;
//        QString sessionName = idx.data(Qt::DisplayRole).toString();
//        if (m_expandedSessions.contains(sessionName)) {
//            QStringList projects = SessionManager::projectsForSessionName(sessionName);
//            h += projects.size() * 40 + LINK_HEIGHT;
//        }
//        return QSize(380, h);
//    }

//    bool editorEvent(QEvent *ev, QAbstractItemModel *model,
//        const QStyleOptionViewItem &option, const QModelIndex &idx) final
//    {
//        if (ev->type() == QEvent::MouseButtonRelease) {
//            const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(ev);
//            const Qt::MouseButtons button = mouseEvent->button();
//            const QPoint pos = static_cast<QMouseEvent *>(ev)->pos();
//            const QRect rc(option.rect.right() - 24, option.rect.top(), 24, SESSION_LINE_HEIGHT);
//            const QString sessionName = idx.data(Qt::DisplayRole).toString();
//            if (rc.contains(pos) || button == Qt::RightButton) {
//                // The expand/collapse "button".
//                if (m_expandedSessions.contains(sessionName))
//                    m_expandedSessions.removeOne(sessionName);
//                else
//                    m_expandedSessions.append(sessionName);
//                model->layoutChanged({QPersistentModelIndex(idx)});
//                return true;
//            }
//            if (button == Qt::LeftButton) {
//                // One of the action links?
//                const auto sessionModel = qobject_cast<SessionModel *>(model);
//                QTC_ASSERT(sessionModel, return false);
//                if (m_activeSwitchToRect.contains(pos))
//                    sessionModel->switchToSession(sessionName);
//                else if (m_activeActionRects[0].contains(pos))
//                    sessionModel->cloneSession(ICore::mainWindow(), sessionName);
//                else if (m_activeActionRects[1].contains(pos))
//                    sessionModel->renameSession(ICore::mainWindow(), sessionName);
//                else if (m_activeActionRects[2].contains(pos))
//                    sessionModel->deleteSession(sessionName);
//                return true;
//            }
//        }
//        if (ev->type() == QEvent::MouseMove) {
//            model->layoutChanged({QPersistentModelIndex(idx)}); // Somewhat brutish.
//            //update(option.rect);
//            return true;
//        }
//        return false;
//    }

//private:
//    const QColor hoverColor = themeColor(Theme::Welcome_HoverColor);
//    const QColor textColor = themeColor(Theme::Welcome_TextColor);
//    const QColor linkColor = themeColor(Theme::Welcome_LinkColor);
//    const QColor disabledLinkColor = themeColor(Theme::Welcome_DisabledLinkColor);
//    const QColor backgroundColor = themeColor(Theme::Welcome_BackgroundColor);
//    const QColor foregroundColor1 = themeColor(Theme::Welcome_ForegroundPrimaryColor); // light-ish.
//    const QColor foregroundColor2 = themeColor(Theme::Welcome_ForegroundSecondaryColor); // blacker.

//    QStringList m_expandedSessions;

//    mutable QRect m_activeSwitchToRect;
//    mutable QRect m_activeActionRects[3];
//};

//class ProjectDelegate : public BaseDelegate
//{
//    QString entryType() override
//    {
//        return ProjectWelcomePage::tr("project", "Appears in \"Open project <name>\"");
//    }
//    int shortcutRole() const override { return ProjectModel::ShortcutRole; }

//public:
//    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final
//    {
//        QRect rc = option.rect;

//        const bool hovered = option.widget->isActiveWindow() && option.state & QStyle::State_MouseOver;
//        if (hovered)
//            painter->fillRect(rc, themeColor(Theme::Welcome_HoverColor));

//        const int x = rc.x();
//        const int y = rc.y();
//        const int firstBase = y + 18;
//        const int secondBase = firstBase + 19;

//        static const QPixmap projectIcon = pixmap("project", Theme::Welcome_ForegroundSecondaryColor);
//        painter->drawPixmap(x + 11, y + 6, projectIcon);

//        QString projectName = idx.data(Qt::DisplayRole).toString();
//        QString projectPath = idx.data(ProjectModel::FilePathRole).toString();

//        painter->setPen(themeColor(Theme::Welcome_ForegroundSecondaryColor));
//        painter->setFont(sizedFont(10, option.widget));

//        if (idx.row() < 9)
//            painter->drawText(x + 3, firstBase, QString::number(idx.row() + 1));

//        painter->setPen(themeColor(Theme::Welcome_LinkColor));
//        painter->setFont(sizedFont(13, option.widget, hovered));
//        painter->drawText(x + 36, firstBase, projectName);

//        painter->setPen(themeColor(Theme::Welcome_ForegroundPrimaryColor));
//        painter->setFont(sizedFont(13, option.widget));
//        QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(projectPath));
//        painter->drawText(x + 36, secondBase, pathWithTilde);
//    }

//    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &idx) const final
//    {
//        QString projectName = idx.data(Qt::DisplayRole).toString();
//        QString projectPath = idx.data(ProjectModel::FilePathRole).toString();
//        QFontMetrics fm(sizedFont(13, option.widget));
//        int width = std::max(fm.width(projectName), fm.width(projectPath)) + 36;
//        return QSize(width, 48);
//    }

//    bool editorEvent(QEvent *ev, QAbstractItemModel *,
//        const QStyleOptionViewItem &, const QModelIndex &idx) final
//    {
//        if (ev->type() == QEvent::MouseButtonRelease) {
//            const QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(ev);
//            const Qt::MouseButtons button = mouseEvent->button();
//            if (button == Qt::LeftButton) {
//                const QString projectFile = idx.data(ProjectModel::FilePathRole).toString();
//                ProjectExplorerPlugin::openProjectWelcomePage(projectFile);
//                return true;
//            }
//        }
//        return false;
//    }
//};

class TreeView : public QTreeView
{
public:
    TreeView(QWidget *parent)
        : QTreeView(parent)
    {
        header()->hide();
        setMouseTracking(true); // To enable hover.
        setIndentation(0);
        setSelectionMode(QAbstractItemView::NoSelection);
        setFrameShape(QFrame::NoFrame);
        setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
        setFocusPolicy(Qt::NoFocus);

        QPalette pal;  // Needed for classic theme (only).
        pal.setColor(QPalette::Base, parent->palette().color(QPalette::Background));
        viewport()->setPalette(pal);
    }

    void leaveEvent(QEvent *) final
    {
        QHoverEvent hev(QEvent::HoverLeave, QPointF(), QPointF());
        viewportEvent(&hev); // Seemingly needed to kill the hover paint.
    }
};


/**
 * @brief 项目的欢迎界面，包括按钮一些。
 *
 */
class SessionsPage : public QWidget
{
public:
    SessionsPage(ProjectWelcomePage *projectWelcomePage)
    {
        // FIXME: Remove once facilitateQml() is gone.
//        if (!projectWelcomePage->m_sessionModel)
//            projectWelcomePage->m_sessionModel = new SessionModel(this);
//        if (!projectWelcomePage->m_projectModel)
//            projectWelcomePage->m_projectModel = new ProjectModel(this);

        auto newButton = new WelcomePageButton(this);
        newButton->setText(ProjectWelcomePage::tr("New Project"));
//        newButton->setIcon(pixmap("new", Theme::Welcome_ForegroundSecondaryColor));
        newButton->setOnClicked([] {
            PF_ProjectExplorerPlugin::openNewProjectDialog();
        });

        auto divider = new QWidget(this);
        divider->setMaximumWidth(1);
        divider->setMinimumWidth(1);
        divider->setAutoFillBackground(true);
        divider->setBackgroundRole(QPalette::ButtonText);

        auto openButton = new WelcomePageButton(this);
        openButton->setText(ProjectWelcomePage::tr("Open Project"));
//        openButton->setIcon(pixmap("open", Theme::Welcome_ForegroundSecondaryColor));
        openButton->setOnClicked([] {
            PF_ProjectExplorerPlugin::openOpenProjectDialog();
        });

//        auto sessionsLabel = new QLabel(this);
//        sessionsLabel->setFont(sizedFont(16, this));
//        sessionsLabel->setText(ProjectWelcomePage::tr("Sessions"));

        auto recentProjectsLabel = new QLabel(this);
        recentProjectsLabel->setFont(sizedFont(24, this));
        recentProjectsLabel->setText(ProjectWelcomePage::tr("Recent Projects"));

//        auto sessionsList = new TreeView(this);
//        sessionsList->setModel(projectWelcomePage->m_sessionModel);
//        sessionsList->header()->setSectionHidden(1, true); // The "last modified" column.
//        sessionsList->setItemDelegate(&m_sessionDelegate);
//        sessionsList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

        auto projectsList = new TreeView(this);
        projectsList->setUniformRowHeights(true);
//        projectsList->setModel(projectWelcomePage->m_projectModel);
//        projectsList->setItemDelegate(&m_projectDelegate);
        projectsList->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

        auto hbox11 = new QHBoxLayout;
        hbox11->setContentsMargins(0, 0, 0, 0);
        hbox11->addWidget(newButton);
        hbox11->addStretch(1);

        auto hbox21 = new QHBoxLayout;
        hbox21->setContentsMargins(0, 0, 0, 0);
        hbox21->addWidget(openButton);
        hbox21->addStretch(1);

        auto vbox1 = new QVBoxLayout;
        vbox1->setContentsMargins(0, 0, 0, 0);
        vbox1->addStrut(200);
        vbox1->addItem(hbox11);
        vbox1->addSpacing(16);
//        vbox1->addWidget(sessionsLabel);
//        vbox1->addSpacing(21);
        vbox1->addStretch();
//        vbox1->addWidget(sessionsList);

        auto vbox2 = new QVBoxLayout;
        vbox2->setContentsMargins(0, 0, 0, 0);
        vbox2->addItem(hbox21);
        vbox2->addSpacing(16);
        vbox2->addWidget(recentProjectsLabel);
        vbox2->addSpacing(21);
        vbox2->addWidget(projectsList);

        auto hbox = new QHBoxLayout(this);
        hbox->setContentsMargins(30, 27, 0, 27);
        hbox->addItem(vbox1);
        hbox->addSpacing(16);
        hbox->addWidget(divider);
        hbox->addSpacing(16);
        hbox->addItem(vbox2);
        hbox->setStretchFactor(vbox2, 2);
    }

//    SessionDelegate m_sessionDelegate;
//    ProjectDelegate m_projectDelegate;
};

QWidget *ProjectWelcomePage::createWidget() const
{
    return new SessionsPage(const_cast<ProjectWelcomePage *>(this));
}

//} // namespace Internal
} // namespace ProjectExplorer
